/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.vivo.ic.dm;

import com.vivo.ic.VLog;
import com.vivo.ic.dm.impl.DownloadNetChangeInterface;
import com.vivo.ic.dm.impl.DownloadNotiDealer;

import android.content.BroadcastReceiver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;

/**
 * Receives system broadcasts (boot, network connectivity)
 */
public class DownloadReceiver extends BroadcastReceiver {
    private static final String TAG = Constants.PRE_TAG + "DownloadReceiver";
    private static Handler sAsyncHandler;

    static {
        final HandlerThread thread = new HandlerThread("DownloadReceiver");
        thread.start();
        sAsyncHandler = new Handler(thread.getLooper());
    }

    @Override
    public void onReceive(final Context context, final Intent intent) {

        final String action = intent.getAction();
        VLog.i(TAG, "onReceive action: " + action);
        
        DownloadManager manager = DownloadManager.getInstance();
        final DownloadNotiDealer notiDealer = manager.getNotiDealer();
        DownloadNetChangeInterface netDealer = manager.getNetChangeDealer();
        
        if (Intent.ACTION_MEDIA_MOUNTED.equals(action)) {
            DownloadManager.startDownloadService(context, "ACTION_MEDIA_MOUNTED");

        } else if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
            netDealer.handleNetChange();

        } else if (Downloads.Action.DOWNLOAD_RETRY.equals(action)) {
            DownloadManager.startDownloadService(context, "DOWNLOAD_RETRY");

        } else if (Downloads.Action.NOTI_DOWNLOAD_CLICKED.equals(action)
                || Downloads.Action.NOTI_COMPLETE_CLICKED.equals(action)
                || Downloads.Action.NOTI_HIDE.equals(action)) {
            // 排队处理事务，防止anr
            final PendingResult result = goAsync();
            if (result == null) {
                handleNotificationBroadcast(context, intent, notiDealer);
            } else {
                sAsyncHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        handleNotificationBroadcast(context, intent, notiDealer);
                        result.finish();
                    }
                });
            }
        } else if (Downloads.Action.NOTI_CONFIRM.equals(action)) {
            notiDealer.onNotiNetPauseClicked(context);
        }
    }

    /**
     * Handle any broadcast related to a system notification.
     */
    private void handleNotificationBroadcast(Context context, Intent intent, DownloadNotiDealer notifier) {
        final String action = intent.getAction();
        if (Downloads.Action.NOTI_COMPLETE_CLICKED.equals(action)) {
            final long id = ContentUris.parseId(intent.getData());
            VLog.i(TAG, "NOTI_COMPLETE_CLICKED of id " + id);
            
            hideNotification(context, id);
            notifier.onNotiCompleteClicked(context, id);
            
        } else if (Downloads.Action.NOTI_HIDE.equals(action)) {
            final long id = ContentUris.parseId(intent.getData());
            VLog.i(TAG, "NOTI_HIDE of id " + id);
            
            hideNotification(context, id);
            notifier.onNotiCompleteHiden(context, id);
            
        } else if (Downloads.Action.NOTI_DOWNLOAD_CLICKED.equals(action)) {
            VLog.i(TAG, "NOTI_DOWNLOAD_CLICKED ");
            notifier.onNotiDownloadClicked(context);
            
        }
    }

    /**
     * Mark the given {@link DownloadManager#COLUMN_ID} as being acknowledged by
     * user so it's not renewed later.
     */
    private void hideNotification(Context context, long id) {
        final int status;
        final int visibility;

        final Uri uri = ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, id);
        final Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
        try {
            if (cursor.moveToFirst()) {
                status = getInt(cursor, Downloads.Column.STATUS);
                visibility = getInt(cursor, Downloads.Column.VISIBILITY);
            } else {
                VLog.w(TAG, "Missing details for download " + id);
                return;
            }
        } finally {
            cursor.close();
        }

        if (Downloads.Impl.isStatusCompleted(status) &&
                (visibility == Downloads.Impl.VISIBILITY_VISIBLE_COMPLETED
                || visibility == Downloads.Impl.VISIBILITY_VISIBLE)) {
            final ContentValues values = new ContentValues();
            values.put(Downloads.Column.VISIBILITY, Downloads.Impl.VISIBILITY_VISIBLE_PROGRESS);
            context.getContentResolver().update(uri, values, null, null);
        }
    }

    private static int getInt(Cursor cursor, String col) {
        return cursor.getInt(cursor.getColumnIndexOrThrow(col));
    }
}
